﻿using Microsoft.AspNetCore.Builder;
using Service.Framework.Utils;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Service.Core.Swagger.Filters;
using Swashbuckle.AspNetCore.Filters;

namespace Service.Core.Swagger
{
    public static class ServiceSwaggerExtensions
    {

        /// <summary>
        /// 添加swagger 服务
        /// </summary>
        /// <param name="builder"></param>
        public static void AddSwaggerService(this WebApplicationBuilder builder)
        {
            var services = builder.Services;
            var appName = Tools.GetAppName(builder.Environment.ApplicationName);
            var namespacePrefix = Tools.GetNamespacePrefix(builder.Environment.ApplicationName);
            // Swagger 注册Swagger生成器，定义一个和多个Swagger 文档
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo
                {
                    Title = appName,
                    Description = appName + "：swagger接口开发文档",
                });

                options.AddServer(new OpenApiServer()
                {
                    Url = $"/{appName}",
                    Description = appName + "：swagger接口开发文档",
                });
                options.AddServer(new OpenApiServer()
                {
                    Url = $"/",
                    Description = appName + "：swagger接口开发文档",
                });



                options.CustomOperationIds(apiDesc =>
                {
                    var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
                    return controllerAction.ControllerName + "-" + controllerAction.ActionName;
                });
                options.CustomSchemaIds(type => type.FullName);

                //为 Swagger JSON and UI设置xml文档注释路径
                Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory)
                    .Where(w => w.EndsWith(".xml") && w.Contains(namespacePrefix))
                    .Select(w => w)
                    .ToList()
                    .ForEach(w => options.IncludeXmlComments(w, true));
                #region Jwt token 配置



                options.OperationFilter<AddResponseHeadersFilter>();
                options.OperationFilter<FileUploadOperation>();
                //开启 oauth2 安全描述
                options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}（注意两者之间是一个空格）\"",
                    In = ParameterLocation.Header,
                    Name = "Authorization",
                    Type = SecuritySchemeType.ApiKey,
                    //Scheme = "basic",
                });

                //添加Jwt验证设置,添加请求头信息
                options.AddSecurityRequirement(new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Id = "Bearer",
                            Type = ReferenceType.SecurityScheme
                        }
                    },
                    new List<string>()
                }
            });

                options.DocumentFilter<HiddenApiFilter>();

                #endregion
            });
        }

        /// <summary>
        /// 添加swagger中间件
        /// </summary>
        /// <param name="webApplication"></param>
        public static void AddSwaggerConfigure(this WebApplication webApplication)
        {
            var appName = Tools.GetAppName(webApplication.Environment.ApplicationName);

            if (webApplication.Environment.IsDevelopment())
            {
                // 启用Swagger中间件
                webApplication.UseSwagger();
                // 配置SwaggerUI
                webApplication.UseSwaggerUI(c =>
                {
                    c.SwaggerEndpoint($"/swagger/v1/swagger.json", appName);
                });
            }
        }
    }
}
